﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
 C#扩展方法
 定义：能够向现有类添加方法，而无需修改原始类或创建新的派生类。
 要素：
 1.扩展方法必须在非泛型的静态类中。
 2.第一个参数使用this关键字指定被扩展类型。
 3.建议在扩展方法所在类上，添加命名空间Common(通用)。对其他命名空间可选择使用
*/
//碰到了一个不能改的类用扩展方法
//什么时候用委托，方法体内部有一个逻辑是活的

namespace Common
{
	/// <summary>
    /// 数组助手
    /// </summary>
	public static class ArrayHelper
    {
        //1.升序排序
        //对象数组 Enemy[]
        //逻辑：对象中的某个属性
        //public static void OrderBy<Q>(EnemyTest[] array, Func<EnemyTest,Q> handler) where Q: IComparable

        /// <summary>
        /// 对象数组的升序排列
        /// </summary>
        /// <typeparam name="T">对象的类型 例如：Enemy</typeparam>
        /// <typeparam name="Q">对象的属性 例如：HP</typeparam>
        /// <param name="array">对象数组</param>
        /// <param name="handler">排序依据</param>
        public static void OrderBy<T,Q>(this T[] array, Func<T,Q> handler) where Q: IComparable//泛型约束T要继承IComparable接口
        {
            for (int i = 0; i < array.Length - 1; i++)
            {
                for (int j = i + 1; j < array.Length; j++)
                {
                    //int a = 1, b = 2;
                    //bool c = a > b;
                    //bool d = a.CompareTo(b) > 0;

                    //if (array[i].ATK > array[j].ATK)
                    //if (Fun1(array[i]) > Fun1(array[j]))
                    //if (handler(array[i]) > handler(array[j]))//不可以直接比较,用CompareTo
                    //一劳永逸
                    if (handler(array[i]).CompareTo(handler(array[j])) > 0)
                    {
                        //EnemyTest temp = array[i];
                        T temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }

        ////练习1：定义对象数组降序排列方法
        public static void OrderByDescending<T, Q>(this T[] array, Func<T, Q> handler) where Q : IComparable//泛型约束T要继承IComparable接口
        {
            for (int i = 0; i < array.Length - 1; i++)
            {
                for (int j = i + 1; j < array.Length; j++)
                {
                    //int a = 1, b = 2;
                    //bool c = a > b;
                    //bool d = a.CompareTo(b) > 0;

                    //if (array[i].ATK > array[j].ATK)
                    //if (Fun1(array[i]) > Fun1(array[j]))
                    //if (handler(array[i]) > handler(array[j]))//不可以直接比较,用CompareTo
                    //一劳永逸
                    if (handler(array[i]).CompareTo(handler(array[j])) < 0)
                    {
                        //EnemyTest temp = array[i];
                        T temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }
        //private static float Fun1(EnemyTest enemy)
        //{
        //    return enemy.ATK;
        //}
        //private static int Fun2(EnemyTest enemy)
        //{
        //    return enemy.HP;
        //}
        /// <summary>
        /// 方位太广，不建议使用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array"></param>
        /// <param name="handler"></param>
        public static void BubbleSortFinal<T>(this T[] array, Func<T, T, bool> handler)
        {//2 8 6 1
         //两两比较 满足条件的放到前面

            for (int j = 0; j < array.Length - 1; j++)
            {
                for (int i = j + 1; i < array.Length; i++)
                {
                    //发现更大的交换
                    //if (array[j] < array[i])
                    //3.调用委托 间接执行方法
                    if (handler(array[j], array[i]))
                    {
                        //交换
                        T temp = array[j];
                        array[j] = array[i];
                        array[i] = temp;
                    }
                }
            }
        }

        //练习2：查找满足条件的所有对象
        //应用：查找所有活的敌人
        /// <summary>
        /// 查找所有满足条件的对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="array">对象数组</param>
        /// <param name="condition">查找条件</param>
        /// <returns></returns>
        public static T[] FindAll<T>(this T[] array, Func<T,bool> condition)
        {
            List<T> list = new List<T>(array.Length);
            for (int i = 0; i < array.Length; i++)
            {
                if (condition(array[i]))
                {
                    list.Add(array[i]);
                }
            }
            return list.ToArray();
        }


        //练习3：筛选对象
        //应用：GameObject[] -> Transform[]
        /// <summary>
        /// 筛选对象数组
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <typeparam name="Q">筛选结果类型</typeparam>
        /// <param name="array">需要筛选的对象数组</param>
        /// <param name="handler">筛选逻辑</param>
        /// <returns></returns>
        public static Q[] Select<T,Q>(this T[] array, Func<T, Q> handler)
        {
            Q[] newArray = new Q[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                newArray[i] = handler(array[i]);
            }
            return newArray;
        }
        //练习4：查找指定条件的最大元素
        //应用：获取血量最高的敌人,获取最近的敌人
        //public static int GetMax(int[] array)
        //{
        //    int max = array[0];
        //    for (int i = 0; i < array.Length; i++)
        //    {
        //        if (max<array[i])
        //        {
        //            max = array[i];
        //        }
        //    }
        //    return max;
        //}
        /// <summary>
        /// 获取指定条件的最大元素
        /// </summary>
        /// <typeparam name="T">需要查找的对象类型</typeparam>
        /// <typeparam name="Q">需要查找的对象属性</typeparam>
        /// <param name="array">需要查找的对象数组</param>
        /// <param name="condition">查找条件</param>
        /// <returns></returns>
        public static T GetMax<T,Q>(this T[] array,Func<T,Q> condition) where Q:IComparable 
        {
            T max = array[0];
            for (int i = 0; i < array.Length; i++)
            {
                if (condition(max).CompareTo(condition(array[i])) < 0)
                {
                    max = array[i];
                }
            }
            return max;
        }

        //获取最近敌人
        //添加获取最小值方法
        /// <summary>
        /// 获取指定条件的最小元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="Q"></typeparam>
        /// <param name="array"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static T GetMin<T, Q>(this T[] array, Func<T, Q> condition) where Q : IComparable
        {
            T min = array[0];
            for (int i = 0; i < array.Length; i++)
            {
                if (condition(min).CompareTo(condition(array[i])) > 0)
                {
                    min = array[i];
                }
            }
            return min;
        }
        //查找激活对象
        public static T[] FindActiveObj<T>(this T[] array, Func<T, bool> condition)
        {
            List<T> list = new List<T>(array.Length);
            foreach (var item in array)
            {
                if (condition(item))
                {
                    list.Add(item);
                }
            }
            return list.ToArray();
        }

    }
}

